package com.cn.shiro_demo.config;


import com.cn.shiro_demo.model.Permission;
import com.cn.shiro_demo.model.Role;
import com.cn.shiro_demo.model.User;
import com.cn.shiro_demo.service.UserServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Log4j2
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserServiceImpl userService;

    /**
     * @throws Exception
     * @Description:TODO 用于处理Shiro的授权，获取用户的角色和权限信息。
     * @param: [principalCollection]
     * @return: org.apache.shiro.authz.AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("=================进入授权方法");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        User user = (User) principalCollection.getPrimaryPrincipal();
        log.info("=================获取当前用户：{}", user.getUsername());
        //获取用户角色
        List<Role> roleList = userService.findRolesByUserId(user.getId());
        for (Role role : roleList) {
            authorizationInfo.addRole(role.getName());
            log.info("=================获取当前角色：{}", role.getName());
            List<String> permissionsList = userService.findPermissionsByRoleId(role.getId());
            for (String permisName : permissionsList) {
                authorizationInfo.addStringPermission(permisName);
                //获取用户权限
                log.info("=================获取当前权限：{}", permisName);
            }
        }
        return authorizationInfo;
    }

    /**
     * @throws Exception
     * @Description:TODO 用于处理Shiro的认证，验证用户的身份和凭证是否正确。
     * @param: [authenticationToken]
     * @return: org.apache.shiro.authc.AuthenticationInfo
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("=================进入认证方法");
        //获取用户名密码token对象
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //根据用户名获取用户
        User user = userService.findByUsername(token.getUsername());
        if (user == null) {
            throw new UnknownAccountException("用户不存在");
        }
        //提交认证信息
        log.info("=================提交认证信息 当前用户：{}", user);
        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
    }
}
